package com.ruoyi.common.utils;

import com.ruoyi.common.config.Global;
import com.ruoyi.common.json.JSON;
import com.ruoyi.common.json.JSONObject;
import com.ruoyi.common.utils.http.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.IntStream;

/**
 * 获取地址类
 *
 * @author ruoyi
 */
public class AddressUtils {
    private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);

//    public static final String IP_URL = "http://ip.taobao.com/service/getIpInfo.php";

    public static final Map<String, String> ipMap = new ConcurrentHashMap<>();

    public static String getRealAddressByIP(String ip) {
        return getRealAddressByIP("juhe", ip);
    }

    public static String getRealAddressByIP(String api, String ip) {
        String address = "";

        // 内网不查询
        if (IpUtils.internalIp(ip)) {
            return "内网IP";
        }
        if (Global.isAddressEnabled()) {

            if (ipMap.containsKey(ip)) {
                return ipMap.get(ip);
            }

            int keyCnt = ipMap.keySet().size();
            if (keyCnt > 300) {
                String[] arr = ipMap.keySet().toArray(new String[0]);
                Random r = new Random();
                IntStream.range(0, 100).boxed().map(i -> arr[r.nextInt(keyCnt)]).forEach(ipMap::remove);
            }

            switch (api) {
                case "juhe":
                    address =  juhe(ip);
                    break;
                case "taobao":
                    address = taobao(ip);
                    break;
                case "ipApi":
                    address = ipApi(ip);
                    break;
                default:
                    address = "";
            }

            if (!"".equals(address)) {
                ipMap.put(ip, address);
            }
        }
        return address;
    }

    private static String juhe(String ip) {
        String rspStr = HttpUtils.sendGet("http://apis.juhe.cn/ip/ipNew", "key=e73c70434584b2a5ee343f2cc6b49e99&ip=" + ip);
        if (StringUtils.isEmpty(rspStr)) {
            log.error("获取地理位置异常 {}", ip);
            return "";
        }
        JSONObject obj;
        try {
            obj = JSON.unmarshal(rspStr, JSONObject.class);
            String res = obj.getStr("error_code");
            if (!"0".equals(res)) {
                log.error("获取地理位置异常 {}", ip);
                return "";
            }
            JSONObject data = obj.getObj("result");
            String country = data.getStr("Country");
            String province = data.getStr("Province");
            String city = data.getStr("City");
            return (country + " " + province + " " + city).trim();
        } catch (Exception e) {
            log.error("获取地理位置异常 {}", ip);
        }
        return "";
    }


    private static String taobao(String ip) {
        String rspStr = HttpUtils.sendPost("http://ip.taobao.com/service/getIpInfo.php", "ip=" + ip);
        if (StringUtils.isEmpty(rspStr)) {
            log.error("获取地理位置异常 {}", ip);
            return "";
        }
        JSONObject obj;
        try {
            obj = JSON.unmarshal(rspStr, JSONObject.class);
            JSONObject data = obj.getObj("data");
            String region = data.getStr("region");
            String city = data.getStr("city");
            return (region + " " + city).trim();
        } catch (Exception e) {
            log.error("获取地理位置异常 {}", ip);
        }
        return "";
    }

    private static String ipApi(String ip) {
        String rspStr = HttpUtils.sendGet("http://ip-api.com/json/" + ip, "lang=zh-CN");
        if (StringUtils.isEmpty(rspStr)) {
            log.error("获取地理位置异常 {}", ip);
            return "";
        }
        JSONObject obj;
        try {
            obj = JSON.unmarshal(rspStr, JSONObject.class);
            String region = obj.getStr("regionName");
            String city = obj.getStr("city");
            return (region + " " + city).trim();
        } catch (Exception e) {
            log.error("获取地理位置异常 {}", ip);
        }
        return "";
    }
}
